#  Public and for release, CBEC v3.0.01 Build 1909+ [24th May, 2023]
#
#  Copyright(c) Ivyware Pty Ltd 2018-23  (all rights reserved)
#               MELBOURNE, VICTORIA, AUSTRALIA, 3000
#
#  This file is provided as-is by Ivyware Pty Ltd.  No claims are made
#  as to fitness for any particular purpose.  No warranties of any kind
#  are expressed or implied.  The recipient agrees to determine
#  applicability of information provided.
#
#  Ivyware hereby grants the right to freely use the information
#  supplied in this file for the creation of Expert Advisor products
#  supporting the Chartboard Application, and to make copies of this
#  file in any form for internal or external distribution as long as
#  this notice remains attached.
#
#  No waranty or suitability for purpose is implied.
#
#  Simple Python Advisor script that uses RSI indicator, Bullish and
#  Bearish Engulfing reversal paterns
#  NOTES: Above charts need to be active in chart stack for script to
#         proceed through to completion
#       : Requirement is for phython 3.8 to be installed
#       : Based upon Chartboard Extension Classes (CBEC) shipped with
#         Chartboard product
#    ***: Script under development and subject to change without notice***
#

import sys
sys.path.insert(0, 'C:\\Program Files\\Chartboard\\PythonScripts') # CBEC directory
from PythonCBEC import *
import ctypes  # An included library with Python install.   
from datetime import datetime

#
#  Environment variables
#  NOTES: List of current environment variables suitable for debuuging
import os
print ( 'Python environment')
for param in os.environ.keys():
    print ( "%20s %s" % (param,os.environ[param]) )

#
#   Establish Root of which all other objects are descendants
#   NOTES: Effectively the Chartboard application itself
oCRoot = CRoot

#
#   Establish CStack object
#   NOTES: Effectively the View tab under which this python script is running
#          and identified by the 'this' tag
oCStack = oCRoot.CStackFactory('this');
print ( 'CStack Period Units:' + oCStack.sPUnits)
print ( 'CStack Stock Code:' + oCStack.StockCode())
print ( oCStack)
print ( 'CStack Operative Time=' + str(oCStack.dDATE) )
print ( 'CStack Period Units=' + str(oCStack.nPUnits) )
#
#   OHLC Chart test
#   NOTES: Logically OHLC chart needs to exist within the chart stack
oCStack.Prerequisites('OHLC')
if oCStack.ChartExists('OHLC'):
    print ('Testing OHLCv chart components')
    oChartOHLC = oCStack.ChartFactory('OHLCv')
    oChartOHLC.Prerequisites('Reversals-A')
    #
    # Testing DSeriesReversals
    print ('Testing Reversals-A DSeries components')
    oDSeriesReversalsA = oChartOHLC.DSeriesFactory('Reversals-A')
    oDSeriesReversalsA.SetParam_i('RPMask-BULL',(RPMask_BULLs))
    oDSeriesReversalsA.SetParam_i('RPMask-BEAR',(RPMask_BEARs))
    #
    # Testing DrawTag upon chart
    oDrawTag = DrawTag(oChartOHLC,oDSeriesReversalsA)
    oDrawTag.DoDrawTag( PUNITS_Week, 'Buy','Buy tag message')
#
#   RSI Chart test
#   NOTES: Logically RSI chart needs to exist within the chart stack
oCStack.Prerequisites('RSI')
if oCStack.ChartExists('RSI'):
    print ('Testing RSI chart components')
    oChartRSI = oCStack.ChartFactory('RSI')
    #
    # Testing DSeriesRSI
    oDSeriesRSI = oChartRSI.DSeriesFactory('RSI')
    print('RSIperiods='+str(oDSeriesRSI.iRSIperiods))
    print('OBought='+str(oDSeriesRSI.iOBought))
    print('OSold='+str(oDSeriesRSI.iOSold))
    print('Value-RSI='+str(oDSeriesRSI.GetValue_d("RSI",0,0)))

#################################################
#   Process DSeries bars for monthly, weekly and daily period units
#   NOTES: Evaluates buy shade bars based on monthly period data
#          when a BULL_ENGULFING candlestick pattern exist and RSI
#          is less than 50
#        : Evaluates sell shade bars based on monthly period data
#          when a BULL_ENGULFING candlestick pattern exist and RSI
#          is greater than 50
oCStack.PYCB_ShadeBarClear(0);
oCStack.PYCB_ShadeBarMask(0,(1<<SBTYPE_Sell)|(1<<SBTYPE_Buy))
#
#   Monthly buy signals
#   NOTES: Evaluates both buy and sell shade bars using both RSI
#          and candlesticks
if oCStack.ChartExists('RSI') and oCStack.ChartExists('OHLCv') :
    oCStack.Rewind()
    while oCStack.Step(PUNITS_Month,1):
        dRSI = oDSeriesRSI.GetValue_d('RSI',PUNITS_Month,0)
        nReversalsA = oDSeriesReversalsA.GetValue_i('All',PUNITS_Month,0)
        if ( dRSI is not None and dRSI <= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BULL_ENGULFING) > 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Month,0,SBTYPE_Buy,11)
            print('Reversals-A(Month-Bullish)')
        if ( dRSI is not None and dRSI >= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BEAR_ENGULFING) > 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Month,0,SBTYPE_Sell,11)
            print('Reversals-A(Month-Bearish)')
#
#   Weekly buy signals
#   NOTES: Evaluates both buy and sell shade bars using both RSI
#          and candlesticks
if oCStack.ChartExists('RSI') and oCStack.ChartExists('OHLCv') :
    oCStack.Rewind()
    while oCStack.Step(PUNITS_Week,1):
        dRSI = oDSeriesRSI.GetValue_d('RSI',PUNITS_Week,0)
        nReversalsA = oDSeriesReversalsA.GetValue_i('All',PUNITS_Week,0)
        if ( dRSI is not None and dRSI <= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BULL_ENGULFING) != 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Week,0,SBTYPE_Buy,11)
        if ( dRSI is not None and dRSI >= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BEAR_ENGULFING) != 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Week,0,SBTYPE_Sell,11)
#
#   Daily buy signals
#   NOTES: Evaluates both buy and sell shade bars using both RSI
#          and candlesticks
if oCStack.ChartExists('RSI') and oCStack.ChartExists('OHLCv') :
    oCStack.Rewind()
    while oCStack.Step(PUNITS_Day,1):
        dRSI = oDSeriesRSI.GetValue_d('RSI',PUNITS_Day,0)
        nReversalsA = oDSeriesReversalsA.GetValue_i('All',PUNITS_Day,0)
        #oCStack.PYCB_ShadeBarUpdate(PUNITS_Day,0,SBTYPE_Buy,11)
        if ( dRSI is not None and dRSI <= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BULL_ENGULFING) != 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Day,0,SBTYPE_Buy,11)
        if ( dRSI is not None and dRSI >= 50.0 and
             nReversalsA is not None and (nReversalsA&RPType_BEAR_ENGULFING) != 0 ):
            oCStack.PYCB_ShadeBarUpdate(PUNITS_Day,0,SBTYPE_Sell,11)



